package com.kmxd.ams.app.search;

import static com.kmxd.ams.core.common.constant.Constants.SEARCH_SVC_PREFIX;

import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kmxd.ams.client.archive.IArchiveTypeSvc;
import com.kmxd.ams.client.archive.dto.ArchiveTypeQueryDTO;
import com.kmxd.ams.client.archive.vo.ArchiveTypeListVO;
import com.kmxd.ams.client.oss.vo.EfileRecordVO;
import com.kmxd.ams.client.search.ISearchSvc;
import com.kmxd.ams.client.search.dto.*;
import com.kmxd.ams.client.search.vo.*;
import com.kmxd.ams.core.common.constant.ErrorCode;
import com.kmxd.ams.core.exception.BizTipException;
import com.kmxd.ams.core.oss.bo.OssFile;
import com.kmxd.ams.core.util.RedisUtils;
import com.kmxd.ams.infra.arrange.base.SystemBO;
import com.kmxd.ams.infra.search.entity.DocumentEs;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

/**
 * 检索
 *
 * @author nickbi
 */
@Service
@Primary
@RequiredArgsConstructor
public class SearchSvcFactory implements ISearchSvc {
  /** 数据检索service */
  private final Map<String, ISearchSvc> service;

  private final IArchiveTypeSvc archiveTypeSvc;
  private final RedisUtils redisUtils;

  @Value("${ams.search.type:2}")
  private Integer searchType;

  /**
   * 数据检索工厂方法，
   *
   * @param req 请求参数
   * @return 校验结果
   */
  @Override
  public Page archByCondition(SearchByConditionDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + SearchTypeConst.MYSQL);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.archByCondition(req);
  }

  @Override
  public List<Tree<String>> selectArchTree(SearchByKeywordsDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + +SearchTypeConst.MYSQL);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.selectArchTree(req);
  }

  @Override
  public QuickSearchVO quickSearch(QuickSearchDTO req) {
    checkExistsArch();
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.quickSearch(req);
  }

  @Override
  public AdvancedSearchVO advancedSearch(AdvancedSearchDTO req) {
    checkExistsArch();
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.advancedSearch(req);
  }

  @Override
  public CardSearchVO cardSearch(CardSearchDTO req) {
    checkExistsArch();
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.cardSearch(req);
  }

  @Override
  public CatalogSearchVO catalogSearch(CatalogSearchDTO req) {
    checkExistsArch();
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.catalogSearch(req);
  }

  @Override
  public List<Tree<String>> catalogTree(CatalogSearchTreeDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.catalogTree(req);
  }

  @Override
  public SearchViewVO view(SearchViewDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.view(req);
  }

  @Override
  public EfileRecordVO download(SearchFileDownloadDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.download(req);
  }

  @Override
  public OssFile downloadZip(SearchFileZipDownloadDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.downloadZip(req);
  }

  @Override
  public EfileRecordVO preview(SearchFilePreviewDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.preview(req);
  }

  @Override
  public boolean checkAuth(SearchAuthCheckDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.checkAuth(req);
  }

  @Override
  public SearchAuthVO getAuth(SearchAuthQueryDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.getAuth(req);
  }

  @Override
  public List<DocumentEs> quickSearchData(QuickSearchExportDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.quickSearchData(req);
  }

  @Override
  public List<String> quickSearchExport(QuickSearchExportDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.quickSearchExport(req);
  }

  @Override
  public List<? extends SystemBO> advancedSearchData(AdvancedSearchExportDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.advancedSearchData(req);
  }

  @Override
  public List<String> advancedSearchExport(AdvancedSearchExportDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.advancedSearchExport(req);
  }

  @Override
  public List<? extends SystemBO> cardSearchData(CardSearchExportDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.cardSearchData(req);
  }

  @Override
  public List<String> cardSearchExport(CardSearchExportDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.cardSearchExport(req);
  }

  @Override
  public List<? extends SystemBO> catalogSearchData(CatalogSearchExportDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.catalogSearchData(req);
  }

  @Override
  public List<String> catalogSearchExport(CatalogSearchExportDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.catalogSearchExport(req);
  }

  @Override
  public List<SearchViewVO> list(SearchViewListQueryDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.list(req);
  }

  @Override
  public List<String> exportList(SearchViewListQueryDTO req) {
    ISearchSvc svc = service.get(SEARCH_SVC_PREFIX + searchType);
    if (Objects.isNull(svc)) {
      throw BizTipException.instance(ErrorCode.NOT_FOUND, "未找到对应类型的检索服务");
    }
    return svc.exportList(req);
  }

  private void checkExistsArch() {
    List<ArchiveTypeListVO> lists = archiveTypeSvc.selectList(new ArchiveTypeQueryDTO());
    if (lists.isEmpty()) {
      throw BizTipException.instance(ErrorCode.SEARCH_NO_ARCH, "系统没有开放的档案，请联系管理员");
    }
  }
}
